---
title: Выполнение плавающего обновления
weight: 10
description: |-
  Выполнение плавающего обновления с помощью kubectl.
---

<!DOCTYPE html>

<html lang="ru">

<body>

<div class="layout" id="top">

    <main class="content">

        <div class="row">

     <div class="col-md-8">
          <h3>Цели</h3>
                <ul>
                    <li>Выполнить плавающее обновление с помощью kubectl</li>
                </ul>
            </div>

            <div class="col-md-8">
            <h3>Обновление приложения</h3>

            <p>Пользователи надеются, что приложения будут работать круглосуточно, а разработчики в свою очередь хотят развёртывать новые версии приложений по несколько раз в день. В Kubernetes это возможно благодаря механизму плавающих обновлений (rolling updates). <b>Плавающие обновления</b> позволяют обновить деплойменты без простоев, шаг за шагом заменяя старые поды на новые. Новые поды будут запущены на узлах, имеющих достаточно ресурсов.</p>

            <p>В предыдущем модуле мы промасштабировали приложение до нескольких экземпляров. Это необходимо сделать, чтобы иметь возможность обновлять приложение, не влияя на его доступность. По умолчанию максимальное количество подов, которое может быть недоступно во время обновления, и максимальное количество новых подов, которое можно создать, равны 1. Эти две опции могут быть определены в абсолютном значении (числа) или относительном соотношении (проценты).
            В Kubernetes обновления версионируются, поэтому любое обновление деплоймента можно откатить до предыдущей (стабильной) версии.</p>

            </div>
            <div class="col-md-4">
                <div class="content__box content__box_lined">
                    <h3>Краткое содержание:</h3>
                    <ul>
                        <li>Обновление приложения</li>
                    </ul>
                </div>
                <div class="content__box content__box_fill">
                    <p><i>Плавающие обновления последовательно заменяют экземпляры подов на новые, тем самым позволяя обновить деплойменты без простоев</i></p>
                </div>
            </div>
        </div>
        <br>

        <div class="row">
            <div class="col-md-8">
                <h2 style="color: #3771e3;">Обзор плавающих обновлений</h2>
            </div>
        </div>
        <div class="row">
            <div class="col-md-1"></div>
            <div class="col-md-8">
                <div id="myCarousel" class="carousel" data-ride="carousel" data-interval="3000">
                    <ol class="carousel-indicators">
                        <li data-target="#myCarousel" data-slide-to="0" class="active"></li>
                        <li data-target="#myCarousel" data-slide-to="1"></li>
                        <li data-target="#myCarousel" data-slide-to="2"></li>
                        <li data-target="#myCarousel" data-slide-to="3"></li>
                    </ol>
                      <div class="carousel-inner" role="listbox">
                        <div class="item carousel-item active">
                          <img src="/docs/tutorials/kubernetes-basics/public/images/module_06_rollingupdates1.svg" >
                        </div>

                        <div class="item carousel-item">
                          <img src="/docs/tutorials/kubernetes-basics/public/images/module_06_rollingupdates2.svg">
                        </div>

                        <div class="item carousel-item">
                          <img src="/docs/tutorials/kubernetes-basics/public/images/module_06_rollingupdates3.svg">
                        </div>

                        <div class="item carousel-item">
                          <img src="/docs/tutorials/kubernetes-basics/public/images/module_06_rollingupdates4.svg">
                        </div>
                      </div>

                      <a class="left carousel-control" href="#myCarousel" role="button" data-slide="prev">
                        <span class="sr-only ">Предыдущая картинка</span>
                      </a>
                      <a class="right carousel-control" href="#myCarousel" role="button" data-slide="next">
                        <span class="sr-only">Следующая картинка</span>
                      </a>

                    </div>
            </div>
        </div>
        <br>

        <div class="row">
            <div class="col-md-8">
                <p>Подобно масштабированию приложения, если деплоймент доступен извне, при обновлении сервис будет балансировать трафик только между доступными подами. Доступный под — это экземпляр, который может быть запущен для пользователей приложения.</p>

                <p>С помощью плавающих обновлений можно:</p>
                <ul>
                    <li> переводить приложение из одного окружения в другое (через обновления образа контейнера);</li>
                    <li> откатываться к предыдущим версиям;</li>
                    <li> осуществлять непрерывную интеграцию и непрерывную доставку приложений без простоев.</li>

                </ul>

            </div>
            <div class="col-md-4">
                <div class="content__box content__box_fill">
                    <p><i>Если деплоймент был открыт наружу, в процессе обновления сервис будет балансировать трафик только на доступные поды.</i></p>
                </div>
            </div>
        </div>

        <br>

        <div class="row">
            <div class="col-md-8">
                <p> В инструкциях ниже мы обновим приложение до новой версии и потом откатим его обратно.</p>
            </div>
        </div>
        <br>

        <div class="row">
            <div class="col-md-12">
               <h3>Обновление версии приложения</h3>
               <p>Чтобы получить список деплойментов, выполните подкоманду <code>get deployments</code>:
               <code><b>kubectl get deployments</b></code></p>
               <p>Для списка подов — подкоманду <code>get pods</code>:</p>
               <p><code><b>kubectl get pods</b></code></p>
               <p>Чтобы увидеть версию текущего образа в приложении, воспользуйтесь подкомандой <code>describe pods</code> и посмотрите на поле <code>Image</code>:</p>
               <p><code><b>kubectl describe pods</b></code></p>
               <p>Чтобы обновить версию образа приложения до v2, воспользуемся подкомандой <code>set image</code>, для которой укажем имя деплоймента и новую версию нужного образа:</p>
               <p><code><b>kubectl set image deployments/kubernetes-bootcamp kubernetes-bootcamp=jocatalin/kubernetes-bootcamp:v2</b></code></p>
               <p>Эта команда перевела деплоймент на использование другого образа для приложения и инициировала плавающее обновление. Статус новых и старых подов (т. е. тех, которые будут остановлены) можно проверить с помощью подкоманды <code>get pods</code>:</p>
               <p><code><b>kubectl get pods</b></code></p>
            </div>
        </div>
        <div class="row">
            <div class="col-md-12">
               <h3>Шаг 2: валидация обновления</h3>
               <p>Во-первых, убедимся, что приложение работает. Доступный извне IP-адрес и порт узнаем с помощью команды <code>describe service</code>:</p>
               <p><code><b>kubectl describe services/kubernetes-bootcamp</b></code></p>
               <p>Объявим переменную окружения <tt>NODE_PORT</tt> со значением порта нашего узла:</p>
               <p><code><b>export NODE_PORT="$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports 0).nodePort}}')"</b></code><br />
                  <code><b>echo "NODE_PORT=$NODE_PORT"</b></code></p>
               <p>Далее обратимся через <code>curl</code> к проброшенному IP и порту:</p>
               <p><code><b>curl http://"$(minikube ip):$NODE_PORT"</b></code></p>
               <p>Каждый раз при вызове этой команды <code>curl</code> вам будет попадаться другой под. Обратите внимание, что все поды теперь работают с последней версией приложения (v2).</p>
               <p>Проверить статус обновления можно также с помощью подкоманды <code>rollout status</code>:</p>
               <p><code><b>kubectl rollout status deployments/kubernetes-bootcamp</b></code></p>
               <p>Увидеть текущую версию образа приложения можно подкомандой <code>describe pods</code>:</p>
               <p><code><b>kubectl describe pods</b></code></p>
               <p>В поле <code>Image</code> у этого вывода убедитесь, что запущена последняя версия образа (v2).</p>
            </div>
        </div>

        <div class="row">
            <div class="col-md-12">
               <h3>Откат обновления</h3>
               <p>Выполним ещё одно обновление и попробуем развернуть образ, тегированный как <code>v10</code>:</p>
               <p><code><b>kubectl set image deployments/kubernetes-bootcamp kubernetes-bootcamp=gcr.io/google-samples/kubernetes-bootcamp:v10</b></code></p>
               <p>Вызовем <code>get deployments</code>, чтобы увидеть статус деплоймента:</p>
               <p><code><b>kubectl get deployments</b></code></p>
               <p>Обратите внимание, что вывод показывает недостаток желаемого количества доступных подов. Обратимся к подкоманде <code>get pods</code>, чтобы вывести полный список подов:</p>
               <p><code><b>kubectl get pods</b></code></p>
               <p>Здесь обратите внимание, что некоторые поды перешли в статус <tt>ImagePullBackOff</tt>.</p>
               <p>Чтобы получить больше информации о проблеме, выполните подкоманду <code>describe pods</code>:</p>
               <p><code><b>kubectl describe pods</b></code></p>
               <p>В разделе <code>Events</code> вывода по проблемным подам можно увидеть, что новая версия образа (<code>v10</code>) не существует в репозитории.</p>
               <p>Чтобы откатить деплоймент к последней работающей версии, воспользуйтесь подкомандой <code>rollout undo</code>:</p>
               <p><code><b>kubectl rollout undo deployments/kubernetes-bootcamp</b></code></p>
               <p>Команда <code>rollout undo</code> откатывает деплоймент к предыдущему известному состоянию (к образу v2). Обновления версионируются, поэтому можно откатиться к любому предыдущему известному состоянию деплоймента.</p>
               <p>С помощью подкоманды <code>get pods</code> выведем список подов еще раз:</p>
               <p><code><b>kubectl get pods</b></code></p>
               <p>Четыре пода работают. Проверить, какие версии образа развёрнуты в этих подах, можно подкомандой <code>describe pods</code>:</p>
               <p><code><b>kubectl describe pods</b></code></p>
               <p>Деплоймент снова использует стабильную версию приложения (v2). Откат произошёл успешно.</p>
            </div>
        </div>
        <div class="row">
            <div class="col-md-12">
                <p>Не забудьте очистить содержимое вашего локального кластера:</p>
                <p><code><b>kubectl delete deployments/kubernetes-bootcamp services/kubernetes-bootcamp</b></code></p>
            </div>
        </div>


    </main>

</div>

</body>
</html>
